package com.box.realm;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.box.entity.DbAdmin;
import com.box.entity.DbAdminExample;
import com.box.entity.DbAdminExample.Criteria;
import com.box.entity.DbMenus;
import com.box.mapper.AdminMenusMapper;
import com.box.mapper.DbAdminMapper;
import com.box.mapper.DbAdminlogMapper;
import com.box.service.AdminLogService;
import com.box.service.AdminService;
import com.box.utils.SessionUtils;





/**  
*   
* 项目名称：MyBox  
* 类名称：MyRealm  
* 类描述：自定义realm  
* 创建人：君无邪 www.java214.com
* 创建时间：2020年2月4日 下午7:00:36  
* 修改人：Administrator  
* 修改时间：2020年2月4日 下午7:00:36  
* 修改备注：  
* @version   
*   
*/
public class MyRealm extends AuthorizingRealm {

	@Autowired
	private AdminLogService logService;
	
	@Autowired
	private AdminMenusMapper adminMenusMapper;
	
	@Autowired
	private AdminService adminService;
	
	@Value("${USERNAME}")
	private String USERNAME;
	
	private static Logger logger=LoggerFactory.getLogger(MyRealm.class);

	public MyRealm() {
		logger.info("MyRealm====================");
	}

	@Override
	public String getName() {
		return "MyRealm";
	}
	
	/**
	 * realm授权方法 从输入参数principalCollection得到身份信息 根据身份信息到数据库查找权限信息 将权限信息添加给授权信息对象
	 * 返回 授权信息对象(判断用户访问url是否在权限信息中没有体现)
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		DbAdmin admin = (DbAdmin) principals.getPrimaryPrincipal();
	System.out.println(admin+"获取的admin");

		List<String> permsList = null;

		// 系统管理员，拥有最高权限
		System.out.println(admin.getRoleId().longValue()+".................获取的roleId");
		List<DbMenus> menuList = adminMenusMapper.getMenus(admin.getRoleId().longValue());
		permsList = new ArrayList<String>(menuList.size());
		for (DbMenus menu : menuList) {
			System.out.println(menu+".....................menus");
			if (menu.getPerms() != null && !"".equals(menu.getPerms())) {
				permsList.add(menu.getPerms());
			}
		}

		// 用户权限列表
		Set<String> permsSet = new HashSet<String>();
		for (String perms : permsList) {
			if (StringUtils.isBlank(perms)) {
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}

		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}
	/**
	 * 表单认证过滤器认证时会调用自定义Realm的认证方法进行认证，成功回到index.do，再跳转到index.jsp页面
	 *
	 * 前提：表单认证过滤器收集和组织用户名和密码信息封装为token对象传递给此方法
	 *
	 * token:封装了身份信息和凭证信息 2步骤：比对身份 信息；比对凭证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		// TODO Auto-generated method stub
		String username=(String)token.getPrincipal();
		String password=new String((char[]) token.getCredentials());
		System.out.println(username+"..................realm中的username");
		System.out.println(password+"..................realm中的password");
		List<DbAdmin> admin = adminService.login(username, password);
		if(admin!=null&&admin.size()>0){
			SessionUtils.setSessionAttribute( USERNAME, username);
			logService.insertAdminLog(admin.get(0));
			SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(admin.get(0),password, getName());
			return info;
		}else{
			
			return null;
		}

			
		
	}

	/**
	 * 清除所有用户授权信息缓存.
	 */
	public void clearCachedAuthorizationInfo(String principal) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principal, getName());
		clearCachedAuthorizationInfo(principals);
	}

	/**
	 * 清除所有用户授权信息缓存.
	 */
	public void clearAllCachedAuthorizationInfo() {
		Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
		if (cache != null) {
			for (Object key : cache.keys()) {
				cache.remove(key);
			}
		}
	}
}
